<template>
  <div class="_page-container _forge-container" :class="{ _mobile: isMobile }">
    <div class="_spin-area">
      <vue3-lottie
        v-if="isPlay"
        class="_celebrate"
        :loop="false"
        :scale="isMobile ? 1.5 : 1"
        :animation-data="celebrate"
        @onComplete="onPlayComplete"
      />
      <div class="_spin-area-item _bar">
        <div class="_bar-wrapper">
          <div class="flex flex-col gap-0.88rem">
            <label class="text-0.88rem leading-1rem text-hex-6C6C6C">
              Price
            </label>
            <el-input
              :value="amount"
              size="large"
              placeholder="Spin Amount"
              readonly
            >
              <template #prepend>
                <div class="text-hex-fff">$</div>
              </template>
            </el-input>
          </div>
          <div class="_slider">
            <el-slider
              v-model="probability"
              :min="minMax.min"
              :max="minMax.max"
              :step="0.01"
              :show-tooltip="false"
            />
          </div>
          <ul class="_ratio-list">
            <li
              class="_ratio-item"
              :class="{ _active: probability === ratio.value }"
              v-for="ratio in ratios"
              :key="ratio.label"
              @click="probability = ratio.value"
            >
              {{ ratio.label }}
            </li>
          </ul>
        </div>
      </div>
      <div class="_spin-area-item _circle-container">
        <div
          class="relative flex-1 h-0"
          style="aspect-ratio: 1 / 1; min-height: 0"
        >
          <div class="_circle-container-wrapper">
            <circle-slider
              ref="circleSliderRef"
              v-model:progress="probability"
              :max="minMax.max"
              :min="minMax.min"
              :circle-width="14"
              @on-animation-end="onAnimationEnd"
              @on-animation-start="onAnimationStart"
            />
            <div
              class="absolute text-1.13rem leading-1.56rem font-600"
              style="top: 50%; left: 50%; transform: translate(-50%, -50%)"
              :class="{
                'flex flex-col items-center justify-center py-3rem w-10rem h-full overflow-hidden':
                  isMobile,
              }"
              v-if="selectdForgeItem?.default_spin_amount_times"
            >
              <div :class="{ 'text-1rem mb-0.2rem': isMobile }">
                {{ (probability * 100).toFixed(2) }}%
              </div>
              <template v-if="isMobile">
                <div class="flex-1 h-0 flex flex-col w-full">
                  <div
                    class="flex-1 h-0 flex items-center justify-center w-full"
                  >
                    <img
                      class="w-full h-full"
                      style="object-fit: contain"
                      :src="selectdForgeItem?.product?.image"
                    />
                  </div>
                  <div
                    class="_text-small _text-ellipsis text-0.8rem mt-0.2rem w-full text-hex-6C6C6C"
                  >
                    {{ selectdForgeItem?.product?.name }}
                  </div>
                  <div
                    class="_text-middle text-1rem text-center mt-0.5rem mb-0.4rem"
                  >
                    <span>$</span>
                    <span>{{ selectdForgeItem?.product?.amount }}</span>
                  </div>
                  <div class="_text-middle text-1rem text-primary text-center">
                    {{ selectdForgeItem?.default_spin_amount_times }}x
                  </div>
                </div>
              </template>
            </div>
          </div>
        </div>
        <div class="flex items-center" v-if="!isMobile">
          <el-button
            size="large"
            class="flex-[1.5] w-0"
            type="primary"
            :disabled="
              !selectdForgeItem?.default_spin_amount_times || openForgeLoading
            "
            @click="onOpenSpin(OpenForgeType.PROD)"
          >
            <div class="_btn-text text-hex-1D1F20">
              {{
                selectdForgeItem?.default_spin_amount_times
                  ? `Spin for $${amount}`
                  : "Select Product"
              }}
            </div>
          </el-button>
          <el-button
            size="large"
            :disabled="openForgeLoading"
            class="flex-1 w-0"
            type="info"
            @click="onOpenSpin(OpenForgeType.DEMO)"
          >
            <div class="_btn-text">Demo Spin</div>
          </el-button>
        </div>
      </div>
      <div class="_spin-area-item" v-if="!isMobile">
        <div
          v-if="detailLoading"
          class="flex items-center justify-center w-full h-full"
        >
          <loading class="!w-2.5rem" :track-width="6" />
        </div>
        <div v-else class="_forge-product">
          <div
            class="mb-1rem w-full text-primary text-right text-1.31rem leading-1.5rem"
          >
            {{ selectdForgeItem?.default_spin_amount_times }}x
          </div>
          <div class="flex-1 h-0 flex items-center justify-center w-full">
            <img
              class="w-full h-full"
              style="object-fit: contain"
              :src="selectdForgeItem?.product?.image"
            />
          </div>
          <div
            class="mt-2.25rem mb-0.69rem w-full text-hex-6C6C6C text-0.88rem leading-1rem whitespace-nowrap overflow-hidden"
            style="text-overflow: ellipsis"
          >
            {{ selectdForgeItem?.product?.name }}
          </div>
          <div class="text-1.13rem leading-1.56rem">
            <span>$</span>
            <span>{{ selectdForgeItem?.product?.amount }}</span>
          </div>
        </div>
      </div>
    </div>
    <div class="_forge-product-container">
      <div class="_forge-product-search">
        <el-input
          v-model="params.search_content"
          size="large"
          class="_search-input"
          placeholder="Search"
          clearable
          @keyup.enter="onQuery"
          @clear="onQuery"
        >
          <template #prefix>
            <img class="w-1.38rem h-1.38rem" :src="searchIcon" />
          </template>
        </el-input>
        <div class="_search-bar">
          <label>Price By</label>
          <el-select
            v-model="params.price_by"
            size="large"
            class="_select-search-bar"
            placeholder="Recommended"
            clearable
            @change="onQuery"
          >
            <el-option
              v-for="item in priceBy"
              :key="item.value"
              v-bind="item"
            />
          </el-select>
        </div>
      </div>
      <component
        ref="basicTableRef"
        :is="BasicTable<API.Forge.ForgeItem>"
        :request="getForgeList"
        :field-names="{ list: 'forge_list' }"
        :params="params"
        :data-source-mode="
          isMobile ? DataSourceMode.Pagination : DataSourceMode.Loadmore
        "
        @requestEnd="onRequestEnd"
      >
        <template #default="{ list, loading, pageSize }">
          <div class="_forge-box">
            <template v-if="!loading || !isMobile">
              <div
                class="_forge-item _view-wrapper"
                v-for="forge in list"
                :key="forge.id"
                :class="{ _active: selectdForgeItem?.id === forge.id }"
                @click="onSelectForge(forge)"
              >
                <div class="_forge-image-wrapper">
                  <img
                    class="w-full h-full"
                    style="object-fit: contain"
                    :src="forge.product?.image"
                  />
                </div>
                <div class="_forge-item-name" style="text-overflow: ellipsis">
                  {{ forge.product?.name }}
                </div>
                <price-btn
                  :price="Number(forge.product?.amount || 0)"
                  :price-class="{ '!text-0.88rem': isMobile }"
                />

                <img
                  class="_view"
                  :src="ViewGray"
                  @click.stop="openDetail(forge.product)"
                />
              </div>
            </template>
            <template v-if="loading && (list.length === 0 || isMobile)">
              <div class="_forge-item" v-for="item in pageSize" :key="item">
                <div class="flex items-center justify-center h-full w-full">
                  <loading class="!w-2.5rem" :track-width="6" />
                </div>
              </div>
            </template>
          </div>
        </template>
      </component>
    </div>
  </div>

  <div class="_btn-mobile" v-if="isMobile">
    <el-button
      class="_btn"
      size="large"
      type="primary"
      :disabled="
        !selectdForgeItem?.default_spin_amount_times || openForgeLoading
      "
      @click="onOpenSpin(OpenForgeType.PROD)"
    >
      <div class="_btn-text text-hex-1D1F20">
        {{
          selectdForgeItem?.default_spin_amount_times
            ? `Spin for $${amount}`
            : "Select Product"
        }}
      </div>
    </el-button>
    <el-button
      class="_btn"
      size="large"
      :disabled="openForgeLoading"
      type="info"
      @click="onOpenSpin(OpenForgeType.DEMO)"
    >
      <div class="_btn-text">Demo Spin</div>
    </el-button>
  </div>

  <product-detail
    v-model:open="detailModal.toggle"
    :record="detailModal.record"
    @clear="detailModal.record = {}"
  />
</template>

<script lang="tsx" setup>
import { Vue3Lottie } from "vue3-lottie";

import { getForgeDetail, getForgeList } from "@/api/forge";
import celebrate from "@/assets/json/celebrate.json";
import searchIcon from "@/assets/search.png";
import ViewGray from "@/assets/view-gray.png";
import type { BasicTableInstance } from "@/components/BasicTable/basicTable";
import { DataSourceMode } from "@/components/BasicTable/basicTable";
import BasicTable from "@/components/BasicTable/basicTable.vue";
import Loading from "@/components/Loading/loading.vue";
import PriceBtn from "@/components/PriceBtn/price-btn.vue";
import productDetail from "@/components/ProductDetail/productDetail.vue";
import { priceBy } from "@/enum/common";
import { useMedia } from "@/hooks/useMedia";
import { useModalToggle } from "@/hooks/useModalToggle";

import type { CircleSliderInstance } from "./CircleSlider/circleSlider";
import CircleSlider from "./CircleSlider/circleSlider.vue";
import { OpenForgeType, useOpenForge } from "./useOpenForge";
import { useProbability } from "./useProbability";

defineOptions({
  inheritAttrs: false,
});

const detailLoading = ref(true);
const circleSliderRef = ref<CircleSliderInstance>();
const selectdForgeItem = ref<API.Forge.ForgeItem>();
const basicTableRef = ref<BasicTableInstance>();
const params = ref<API.Forge.ForgeListParams>({
  search_content: void 0,
  max_amount: void 0,
});

const isMobile = useMedia();
const route = useRoute();
const router = useRouter();
const { modalToggleInfo: detailModal, onOpenModal: openDetail } =
  useModalToggle<API.Forge.ProductItem>();
const { minMax, probability, amount, ratios } =
  useProbability(selectdForgeItem);
const {
  isPlay,
  openForgeLoading,
  onOpenSpin,
  onPlayComplete,
  onAnimationStart,
  onAnimationEnd,
} = useOpenForge(probability, circleSliderRef);

async function getForgeInfo() {
  if (!route.query.forge_id) {
    return;
  }

  detailLoading.value = true;
  selectdForgeItem.value = await getForgeDetail({
    id: Number(route.query.forge_id),
  });
  detailLoading.value = false;
}

function onQuery() {
  basicTableRef.value?.resetQuery();
}

function onRequestEnd(dataSources: API.Forge.ForgeItem[]) {
  if (!route.query.forge_id) {
    onSelectForge(dataSources?.[0]);
    detailLoading.value = false;
  }
}

function onSelectForge(forge: API.Forge.ForgeItem) {
  selectdForgeItem.value = forge;
  router.push({
    query: {
      forge_id: forge.id,
    },
  });
}

onBeforeMount(() => {
  getForgeInfo();
});
</script>

<style lang="less" scoped>
._forge-container {
  @apply flex-1 flex flex-col;
  gap: 1.81rem;
  padding: 1.38rem 0;
  width: 100%;
  ._spin-area {
    @apply relative flex items-stretch;
    width: 100%;
    aspect-ratio: 78 / 27.63;
    min-height: 0;
    border-radius: var(--el-border-radius-base);
    border: 0.06rem solid #464a4b;
    ._spin-area-item {
      flex: 1;
      width: 0;
      position: relative;
      &::after {
        position: absolute;
        right: 0;
        top: 0;
        bottom: 0;
        width: 1px;
        background-color: #464a4b;
        content: "";
      }
      &:last-child {
        &::after {
          display: none;
        }
      }

      &._bar {
        @apply flex items-center justify-center;
        ._bar-wrapper {
          width: 80%;
        }
        ._slider {
          padding: 1.75rem 0 2.31rem;
        }
        ._ratio-list {
          @apply flex flex-wrap items-center w-full list-none m-0 p-0 cursor-pointer;
          gap: 0.63rem;
          padding: 0 1.19rem;
          ._ratio-item {
            @apply flex items-center justify-center;
            width: calc((100% - 0.63rem * 2) / 3);
            aspect-ratio: 5 / 2.25;
            min-height: 0;
            font-size: 1.13rem;
            line-height: 1.56rem;
            border-radius: var(--el-border-radius-base);
            background-color: #353636;
            user-select: none;
            &:active {
              opacity: 0.8;
            }
          }
        }
      }

      &._circle-container {
        @apply flex flex-col;
        padding: 0 2.5rem 2.5rem;
        ._circle-container-wrapper {
          @apply h-full w-full;
          padding: 1.5rem;
        }
      }

      ._btn-text {
        font-size: 1.13rem !important;
        font-weight: 600;
        line-height: 1.56rem;
      }

      ._forge-product {
        @apply flex flex-col items-start justify-between h-full;
        padding: 1.94rem;
      }
    }

    ._celebrate {
      @apply absolute top-0 left-0 right-0 bottom-0;
    }
  }

  ._forge-product-container {
    @apply flex flex-col;
    gap: 2.19rem;
    ._forge-product-search {
      @apply flex items-center justify-between w-full;
      ._search-input {
        width: 25rem;
      }
      ._search-bar {
        @apply flex items-center;
        gap: 1rem;
        & > label {
          font-size: 1rem;
          line-height: 1.38rem;
          white-space: nowrap;
        }
        ._select-search-bar {
          width: 18.75rem;
        }
      }
    }

    ._forge-box {
      @apply flex flex-wrap items-stretch;
      gap: 1.5rem;
      ._forge-item {
        @apply flex flex-col items-center;
        position: relative;
        padding: 1.06rem 1rem;
        width: calc((100% - 1.5rem * 4) / 5);
        aspect-ratio: 14.38 / 14.25;
        min-height: 0;
        background-color: #232829;
        border-radius: 0.5rem;
        cursor: pointer;
        ._forge-image-wrapper {
          @apply flex-1 h-0;
          padding-top: 0.82rem;
        }

        ._forge-item-name {
          @apply w-full text-hex-9D9D9D;
          margin: 0.94rem 0 0.69rem;
          font-size: 0.88rem;
          line-height: 1rem;
          overflow: hidden;
          white-space: nowrap;
        }

        &::before {
          position: absolute;
          top: 0;
          left: 0;
          width: 100%;
          height: 100%;
          border: 1px solid var(--el-color-primary);
          border-radius: 0.38rem;
          content: "";
          opacity: 0;
          transition: all 0.2s;
        }

        &._active {
          &::before {
            opacity: 1;
          }
        }

        &._view-wrapper {
          position: relative;
          ._view {
            position: absolute;
            width: 1.88rem;
            top: 0.5rem;
            right: 0.56rem;
            cursor: pointer;
            &:hover {
              opacity: 0.8;
            }
            &:active {
              opacity: 0.6;
            }

            &._left {
              top: 1.38rem;
              left: 1.25rem;
            }
          }
        }
      }
    }
  }
}

._forge-container {
  &._mobile {
    gap: 1.25rem;
    padding: 0 0.88rem 2.19rem;
    overflow: hidden;
    ._spin-area {
      @apply flex-col-reverse border-none;
      aspect-ratio: unset;
      ._spin-area-item {
        flex: unset;
        width: 100%;
        &:after {
          display: none;
        }
        &._bar {
          ._bar-wrapper {
            width: 100%;
          }
          ._slider {
            padding: 1.94rem 0 1.25rem;
          }
          ._ratio-list {
            gap: 0.13rem;
            padding: 0;
            ._ratio-item {
              @apply flex-1 w-0;
              aspect-ratio: 3.5 / 2.25;
              min-height: 0;
              font-size: 0.88rem;
            }
          }
        }

        &._circle-container {
          padding: 0;
          height: 17.5rem;
          ._circle-container-wrapper {
            padding: 0;
          }
        }
      }
    }

    ._forge-product-container {
      gap: 1.88rem;
      ._forge-product-search {
        @apply flex-col;
        gap: 1.25rem;
        ._search-bar,
        ._search-input {
          width: 100%;
        }
      }

      ._forge-box {
        gap: 0.81rem;
        ._forge-item {
          padding: 0.8rem;
          width: calc((100% - 0.81rem) / 2);
          ._forge-image-wrapper {
            @apply flex-1 h-0;
            padding-top: 0;
          }
          ._forge-item-name {
            margin: 0.64rem 0 0.54rem;
            font-size: 0.88rem;
            text-align: center;
          }
        }
      }
    }
  }
}

._btn-mobile {
  @apply fixed z-2 bottom-0 left-0 right-0 flex flex-col;
  gap: 1.13rem;
  padding: 1.76rem 0.94rem 0.94rem;
  background-color: rgba(0, 0, 0, 0.8);
  ._btn {
    margin: 0;
    ._btn-text {
      font-size: 1.13rem;
    }
  }
}
</style>

<style lang="less">
._slider {
  padding: 1.75rem 0 2.31rem;
  .el-slider {
    --el-slider-main-bg-color: #17db05;
    --el-slider-border-radius: 0px;
    .el-slider__button {
      border-color: #fff;
      border-width: 3px;
      background-color: var(--el-color-primary);
    }
  }
}
</style>
